package com.xl.singletonPattern.practice;

import java.util.concurrent.BlockingDeque;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.TimeUnit;

/**
 * 数据库连接池单例-使用静态内部类实现
 * 这是线程安全的懒加载方式
 */
public class ConnectionPool {
    //1.私有化构造方式，确保外部不能通过new关键字创建对象
    private ConnectionPool() {
        initializePool();
        System.out.println("数据库连接池初始化完成...");
    }
    //2.创建静态内部类，并定义静态成员变量
    private static class ConnectionPoolHolder {
        private static final ConnectionPool INSTANCE = new ConnectionPool();
    }
    //3.提供静态方法获取单例对象
    public static ConnectionPool getInstance() {
        return ConnectionPoolHolder.INSTANCE;
    }
    //4.定义连接池相关属性
    private BlockingDeque<Connection> pool;
    private final int poolSize = 10;
    private final long mxaWaitTime = 5000;
    /**
     * 初始化连接池
     */
    private void initializePool() {
        pool = new LinkedBlockingDeque<>(poolSize);
        //创建初始链接
        for (int i = 1; i <= poolSize; i++) {
            Connection connection = new Connection("Connection-"+i);
            pool.add(connection);
        }
    }
    /**
     * 获取数据库连接
     * @return 连接对象，如果超时返回null
     */
    public Connection getConnection() {
        return getConnection(mxaWaitTime);
    }
    public Connection getConnection(long timeout) {
        System.out.println(Thread.currentThread().getName()+" 尝试获取数据库连接...");
        try {
            //添加超时机制
            Connection connection = pool.poll(timeout, TimeUnit.MILLISECONDS);
            if (connection != null) {
                System.out.println(Thread.currentThread().getName()+"成功从连接池中获取连接：" + connection.getId()+",剩余连接："+pool.size());
                return connection;
            } else {
                System.out.println(Thread.currentThread().getName()+"获取数据库连接超时...");
                return null;
            }
        } catch (InterruptedException e) {
            System.out.println(Thread.currentThread().getName()+"获取数据库连接被中断...");
            Thread.currentThread().interrupt(); //恢复中断状态
        }
        return null;
    }

    /**
     * 释放连接放回连接池
     * @param connection 待释放的链接
     */
    public void releaseConnection(Connection connection) {
        if (connection != null) {
            boolean released = pool.offer(connection);
            if (released) {
                System.out.println(Thread.currentThread().getName()+"释放连接：" + connection.getId()+",剩余可用连接："+pool.size());
            } else {
                System.out.println("警告：连接池已满，无法释放连接：" + connection.getId());
            }
        }
    }
    /**
     * 尝试立即获取连接，不等待
     * @return 连接对象，如果没有可用连接立即返回null
     */
    public Connection tryGetConnection() {
        Connection conn = pool.poll(); // 立即返回，不阻塞
        if (conn != null) {
            System.out.println(Thread.currentThread().getName() + " 立即获取: " + conn.getId());
        } else {
            System.out.println(Thread.currentThread().getName() + " 无可用连接");
        }
        return conn;
    }
    /**
     * 获取当前可用连接数量
     */
    public int getAvailableConnections() {
        return pool.size();
    }
    /**
     * 获取连接池状态信息
     */
    public String getPoolStatus() {
        return String.format("连接池状态: 总容量=%d, 可用=%d, 已使用=%d",poolSize, pool.size(), poolSize - pool.size());
    }
    /**
     * 模拟数据库连接对象
     */
    public static class Connection {
        private final String id;
        private final long createTime;

        public Connection(String id) {
            this.id = id;
            this.createTime = System.currentTimeMillis();
        }

        public String getId() {
            return id;
        }

        public void executeQuery(String sql) {
            System.out.println("执行SQL：" + sql+" [使用连接："+id+"]");
        }

        public String toString() {
            return "Connection{" +
                    "id='" + id + '\'' +
                    ", createTime=" + createTime +
                    '}';
        }
    }
}
